<template>
  <div class="box">
    <!-- 登录盒子  -->
    <div class="login-box">
      <p><span>CSI员工</span> 之家</p>
      <!-- 登录表单 -->
      <el-form
          class="login-form"
          label-width="0px"
          :model="loginForm"
          ref="loginFormRef"
          :rules="loginFormRules"
      >
        <!-- 用户名 -->
        <el-form-item prop="loginname">
          <el-input
              prefix-icon="iconfont icon-user"
              v-model="loginForm.loginname"
          ></el-input>
        </el-form-item>
        <!-- 密码 -->
        <el-form-item prop="password">
          <el-input @keyup.enter.native="login"
                    prefix-icon="iconfont icon-3702mima"
                    v-model="loginForm.password"
          ></el-input>
          <el-checkbox label="记住我" v-model="checked"></el-checkbox>
          <a href="javascript:void(0)" @click="passworddialogVisible = true"
          >忘记密码?</a
          >
        </el-form-item>
        <!-- 按钮 -->
        <el-form-item class="btns">
          <el-button type="primary" @click="login">登录</el-button>
          <el-button type="info" @click="facelogindialogVisible = true"
          >刷脸
          </el-button
          >
        </el-form-item>
      </el-form>
    </div>
    <!-- 忘记密码对话框 -->
    <el-dialog
        title="忘记密码"
        :visible.sync="passworddialogVisible"
        width="30%"
        :before-close="handleClose"
    >
      <el-form
          ref="form"
          :model="editpwd"
          label-width="80px"
          :rules="phoneRules"
      >
        <el-form-item label="手机号:" prop="phone">
          <el-input
              v-model="editpwd.phone"
              @input="validatePhone"
              placeholder="请输入手机号"
          ></el-input>
        </el-form-item>
        <!-- 验证码 -->
        <el-form-item label="验证码:" prop="code">
          <el-input
              v-model="editpwd.code"
              placeholder="请输入验证码"
              style="width: 60%; display: inline-block"
          ></el-input>
          <el-button
              :disabled="!isPhoneValid || isCounting"
              @click="sendCode"
          >{{ isCounting ? countdown + "秒" : "发送验证码" }}
          </el-button
          >
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="passworddialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="findpwd">确 定</el-button>
      </span>
    </el-dialog>

    <!-- 重置密码对话框 -->
    <el-dialog
        title="忘记密码"
        :visible.sync="resetpassworddialogVisible"
        width="30%"
        :before-close="handleClose1"
    >
      <el-form ref="resetForm" :model="password" label-width="80px" :rules="passwordRules">
        <el-form-item label="新密码:" prop="newPassword">
          <el-input
              v-model="password.newPassword"
              placeholder="请输入新密码"
          ></el-input>
        </el-form-item>
        <el-form-item label="确认密码:" prop="repassword">
          <el-input
              v-model="password.repassword"
              placeholder="请再次输入密码"
          ></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="resetpassworddialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="resetpwd">确 定</el-button>
      </span>
    </el-dialog>
    <!-- 人脸注册 -->
    <el-dialog
        title="人脸登录"
        :visible.sync="facelogindialogVisible"
        width="30%"
        :before-close="handleClose"
    >
      <div class="camera_outer">
        <video
            id="videoCamera"
            :width="videoWidth"
            :height="videoHeight"
            autoplay
        ></video>
        <canvas
            style="display: none"
            id="canvasCamera"
            :width="videoWidth"
            :height="videoHeight"
        ></canvas>
        <div v-if="imgSrc" class="img_bg_camera" style="display: none">
          <img :src="imgSrc" alt class="tx_img"/>
        </div>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="getCompetence()">打开摄像头</el-button>
        <el-button @click="stopNavigator()">关闭摄像头</el-button>
        <el-button type="primary" @click="setImage">登录</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isPhoneValid: false, // 新增加的状态，用以判断手机号码是否有效
      passworddialogVisible: false,
      resetpassworddialogVisible: false,
      editpwd: {
        phone: "",
        code: "",
      },
      password: {
        newPassword: "",
        repassword: "",
      },
      Yzm: "", // 验证码
      facelogindialogVisible: false,
      videoWidth: 450,
      videoHeight: 400,
      imgSrc: "",
      thisCancas: null,
      thisContext: null,
      thisVideo: null,
      loginForm: {
        loginname: "Romay",
        password: "123456",
      },
      userinfo: {
        username: "",
        id: "",
        status: "",
      },
      checked: true, // 新增的状态
      countdown: 30,
      isCounting: false, // 表单验证规则
      loginFormRules: {
        loginname: [
          {required: true, message: "请输入登录名", trigger: "blur"},
          {
            min: 3,
            max: 10,
            message: "登录名长度在 3 到 10 个字符",
            trigger: "blur",
          },
        ],
        password: [
          {required: true, message: "请输入密码", trigger: "blur"},
          {
            min: 6,
            max: 15,
            message: "密码长度在 6 到 15 个字符",
            trigger: "blur",
          },
        ],
      },
      // 手机号码校验规则
      phoneRules: {
        phone: [
          {
            required: true,
            message: "请输入手机号码",
            trigger: "blur",
          },
          {
            min: 11,
            max: 11,
            message: "手机号码不符合",
            trigger: "blur",
          },
          {
            pattern: /^[1][3-9][0-9]{9}$/,
            message: "手机号码格式不正确",
            trigger: "blur",
          },
        ],
        code: [
          {required: true, message: "请输入验证码", trigger: "blur"},
          {
            min: 6,
            max: 6,
            message: "验证码长度为6位",
            trigger: "blur",
          },
        ],
      },
      passwordRules: {
        newPassword: [
          {required: true, message: "请输入新密码", trigger: "blur"},
          {
            min: 6,
            max: 15,
            message: "新密码长度在 6 到 15 个字符",
            trigger: "blur",
          },
        ],
        repassword: [
          {
            required: true,
            message: "请确认密码",
            trigger: "blur",
          },
          {
            validator: this.validatePasswordMatch,
            trigger: "blur",
          },
        ],
      },
    };
  },
  mounted() {
    this.getCookie();
  },
  methods: {
    validatePasswordMatch(rule, value, callback) {
      if (value !== this.password.newPassword) {
        callback(new Error('两次输入的密码不一致'));
      } else {
        callback();
      }
    },
    validatePhone() {
      const phonePattern = /^[1][3-9][0-9]{9}$/;
      this.isPhoneValid = phonePattern.test(this.editpwd.phone); // 更新手机号有效性
    },
    // 发送验证码
    async sendCode() {
      if (!this.isPhoneValid) {
        this.$message.error("请填写有效的手机号");
        return;
      }
      // 进入倒计时逻辑
      this.isCounting = true;
      this.countdown = 30;

      const interval = setInterval(() => {
        if (this.countdown > 0) {
          this.countdown--;
        } else {
          clearInterval(interval);
          this.isCounting = false; // 倒计时结束
        }
      }, 1000);
      // 发送请求
      console.log('要发送的手机号:', this.editpwd.phone);
      const {data: res} = await this.$http.post(`/users/sendCode?phone=${this.editpwd.phone}`);
      this.Yzm = res.data;
      console.log(res);
      console.log(this.Yzm, "验证码");
      if (res.code !== 200) {
        this.$message.error(res.message); // console.log("发送验证码失败:"+res.meta.msg)
        return;
      }
      this.$message.success("验证码发送成功");
    },

    findpwd() {
      //所有校验通过时，发送请求
      this.$refs.form.validate(async (valid) => {
        if (!valid) {
          return; // 如果验证失败，则不进行请求
        }
        try {
          console.log("手机号码：" + this.editpwd.phone + " 验证码：" + this.editpwd.code);
          const response = await this.$http.post('/users/validateCode', {
                phone: this.editpwd.phone,
                code: this.editpwd.code
              },
              {
                headers: {
                  'Content-Type': 'application/json'
                }
              });
          console.log(response);
          if (response.data.flag) {
            // 验证成功，关闭对话框并打开重置密码对话框
            this.passworddialogVisible = false;
            this.resetpassworddialogVisible = true;
          } else {
            // 验证失败，提示用户
            if (response.data.code === "isv.BUSINESS_LIMIT_CONTROL") {
              this.$message.error("发送过于频繁，请稍后再试");
            } else {
              this.$message.error(response.data.message);
            }
          }
        } catch (error) {
          this.$message.error("验证验证码请求失败，请重试");
        }
      });
    },
    // 重置密码
    resetpwd() {
      this.$refs.resetForm.validate(async (valid) => {
        if (!valid) {
          return; // 如果验证失败，则不进行请求
        }
        if (this.password.newPassword !== this.password.repassword) {
          this.$message.error("两次密码输入不一致");
          return;
        }
        // 发送请求
        const {data: res} = await this.$http.put(
            `/users/resetPassword?phone=${this.editpwd.phone}` + "&newPassword=" + this.password.newPassword,
            this.password
        );
        if (res.code !== 200) {
          this.$message.error(res.message);
          return;
        }
        this.$message.success("密码重置成功，请重新登录");
        this.resetpassworddialogVisible = false;
      })
    },

    // 调用权限（打开摄像头功能）
    getCompetence() {
      var _this = this;
      this.thisCancas = document.getElementById("canvasCamera");
      this.thisContext = this.thisCancas.getContext("2d");
      this.thisVideo = document.getElementById("videoCamera");
      // 旧版本浏览器可能根本不支持mediaDevices，我们首先设置一个空对象
      if (navigator.mediaDevices === undefined) {
        navigator.mediaDevices = {};
      }
      // 一些浏览器实现了部分mediaDevices，我们不能只分配一个对象
      // 使用getUserMedia，因为它会覆盖现有的属性。
      // 这里，如果缺少getUserMedia属性，就添加它。
      if (navigator.mediaDevices.getUserMedia === undefined) {
        navigator.mediaDevices.getUserMedia = function (constraints) {
          // 首先获取现存的getUserMedia(如果存在)
          var getUserMedia =
              navigator.webkitGetUserMedia ||
              navigator.mozGetUserMedia ||
              navigator.getUserMedia;
          // 有些浏览器不支持，会返回错误信息
          // 保持接口一致
          if (!getUserMedia) {
            return Promise.reject(
                new Error("getUserMedia is not implemented in this browser")
            );
          }
          // 否则，使用Promise将调用包装到旧的navigator.getUserMedia
          return new Promise(function (resolve, reject) {
            getUserMedia.call(navigator, constraints, resolve, reject);
          });
        };
      }
      var constraints = {
        audio: false,
        video: {
          width: this.videoWidth,
          height: this.videoHeight,
          transform: "scaleX(-1)",
        },
      };
      navigator.mediaDevices
          .getUserMedia(constraints)
          .then(function (stream) {
            // 旧的浏览器可能没有srcObject
            if ("srcObject" in _this.thisVideo) {
              _this.thisVideo.srcObject = stream;
            } else {
              // 避免在新的浏览器中使用它，因为它正在被弃用。
              _this.thisVideo.src = window.URL.createObjectURL(stream);
            }
            _this.thisVideo.onloadedmetadata = function () {
              _this.thisVideo.play();
            };
          })
          .catch((err) => {
            console.log(err);
          });
    },
    //  绘制图片（拍照功能）
    async setImage() {
      var _this = this;
      if (!_this.thisContext) {
        return this.$message.error("请先打开摄像头");
      }
      // 点击，canvas画图
      // console.log(_this.thisContext.drawImage)
      _this.thisContext.drawImage(
          _this.thisVideo,
          0,
          0,
          _this.videoWidth,
          _this.videoHeight
      );
      // 获取图片base64链接
      var image = this.thisCancas.toDataURL("image/png");
      _this.imgSrc = image;

      // 使用 FormData 发送请求
      const formData = new FormData();
      formData.append("file", this.dataURLtoFile(image, 'face.png'));
      const {data: res} = await this.$http.post("/face/login", formData, {
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      });
      console.log("人脸登录的返回值：" + res);
      if (res.code === 200) {
        // 保存token
        window.sessionStorage.setItem("token", res.data[0]);
        this.userinfo.id = res.data[1];
        this.userinfo.username = res.data[2];
        this.userinfo.status = res.data[3];
        window.sessionStorage.setItem("userinfo", JSON.stringify(this.userinfo));
        _this.$router.push("/home");
        this.$message.success(res.message);
        this.facelogindialogVisible = false;
      } else {
        this.$message.error(res.message);
        this.facelogindialogVisible = false;
      }

    },
    // base64转文件
    dataURLtoFile(dataurl, filename) {
      var arr = dataurl.split(",");
      var mime = arr[0].match(/:(.*?);/)[1];
      var bstr = atob(arr[1]);  // 这里 arr[1] 应该是有效的 Base64 字符串
      var n = bstr.length;
      var u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new File([u8arr], filename, {type: mime});
    },
    // 关闭摄像头
    stopNavigator() {
      this.thisVideo.srcObject.getTracks()[0].stop();
    },
    // // 添加表单重置方法
    // resetLoginForm () {
    //   // this=>当前组件对象，其中的属性$refs包含了设置的表单ref
    //   //   console.log(this)
    //   this.$refs.LoginFormRef.resetFields()
    // },

    //登录方法
    login() {
      try {
        // 点击登录的时候先调用validate方法验证表单内容是否有误
        this.$refs.loginFormRef.validate(async (valid) => {
          // console.log(this.loginFormRules);
          // 如果valid参数为true则验证通过
          if (!valid) {
            return;
          }
          // 发送请求进行登录
          const {data: res} = await this.$http.post("/users/login", this.loginForm);
          // console.log(res);
          if (res.code !== 200) {
            return this.$message.error("登录失败:" + res.message); // console.log("登录失败:"+res.meta.msg)
          }
          this.$message.success(res.message);
          // 保存token
          window.sessionStorage.setItem("token", res.data[0]);

          //将res.data中剩余的数据保存到userinfo中
          this.userinfo.id = res.data[1];
          this.userinfo.username = res.data[2];
          this.userinfo.status = res.data[3];
          // console.log(window.sessionStorage.getItem("token") + "@@@@@@@@@@@@");
          window.sessionStorage.setItem(
              "userinfo",
              JSON.stringify(this.userinfo)
          );
          // 导航至/home
          this.$router.push("/home"); // location.href
        });
      } catch (error) {
        console.error("错误信息", error);
      }
    },

    //设置cookie
    setCookie(c_name, c_pwd, exdays) {
      var exdate = new Date(); //获取时间
      exdate.setTime(exdate.getTime() + 24 * 60 * 60 * 1000 * exdays); //保存的天数
      //字符串拼接cookie
      window.document.cookie =
          "userName" + "=" + c_name + ";path=/;expires=" + exdate.toGMTString();
      window.document.cookie =
          "userPwd" + "=" + c_pwd + ";path=/;expires=" + exdate.toGMTString();
    },
    //读取cookie
    getCookie: function () {
      if (document.cookie.length > 0) {
        var arr = document.cookie.split("; "); //这里显示的格式需要切割一下自己可输出看下
        for (var i = 0; i < arr.length; i++) {
          var arr2 = arr[i].split("="); //再次切割
          //判断查找相对应的值
          if (arr2[0] == "userName") {
            this.loginForm.loginname = arr2[1]; //保存到保存数据的地方
          } else if (arr2[0] == "userPwd") {
            this.loginForm.password = arr2[1];
          }
        }
      }
    },
    //清除cookie
    clearCookie: function () {
      this.setCookie("", "", -1); //修改2值都为空，天数为负1天就好了
    },
    showPassword: function () {
      if (this.passwordType == "text") {
        this.passwordType = "password";
      } else {
        this.passwordType = "text";
      }
    },
    handleClose() {
      this.facelogindialogVisible = false;
      this.passworddialogVisible = false;
    },
    handleClose1() {
      this.resetpassworddialogVisible = false;
    },
  },
};
</script>

<style lang="less" scoped>
.box {
  position: relative;
  height: 100%;
  background: url(../assets/img/bg.png) no-repeat;
  background-size: cover;
}

.login-box {
  width: 450px;
  height: 300px;
  background: #fff;
  border-radius: 10px;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);

  p {
    height: 100%;
    width: 100%;
    font-size: 32px;
    text-align: center;
    font-weight: bold;
    color: #ff9a4c;

    span {
      color: #3bc5bb;
    }
  }
}

.login-form {
  position: absolute;
  bottom: 0;
  width: 100%;
  padding: 0 20px;
  box-sizing: border-box;
}

.btns {
  display: flex;
  justify-content: flex-end;
}

.camera_outer video {
  margin-left: 9px;
}

a {
  text-decoration: none;
  float: right;
  color: #3bc5bb;
}
</style>
  
  